var LOSS = 0;
var WIN = 1;
var DRAW = 2;

var accessToken = "139436992894387|65471b8b3fdc60240f6b3a9e14284c1f";
var board = new Array(3);
var playersPictures = new Array(2);
var lastPlayerInChat;
var numberOfChatMessages = 0;
var draggingChatWindow = false;
var dragChatX;
var dragChatY;
var chatOriginalRight;
var chatOriginalBottom;
var droppableSquares = new Array(8);
var players;
var me;
var lastMessage;

function initialize(){
	playersPictures[0] = "images/checkers/user_picture.gif";
	playersPictures[1] = "images/checkers/user_picture.gif";

	createWebSocketConnection();
	initializeBoard();
	bindChatWindow();
	
	$("#chat_send").bind("keypress", function(event){
		if (event.keyCode == 13){
			sendChatMessage($("#chat_send").val());
			$("#chat_send").val("");
		}
	});
}
/***********************
/* Websocket functions *
/***********************/

function createWebSocketConnection(){
	ws = new WebSocket("ws://localhost:8080/playground/WebSocketServlet/tictactoe");
	ws.onopen = function(event) {
		console.log("connection opened");
		var msg = {action: "registerPlayerToSocket", playerId: $.cookie("playerId"), playerKey: $.cookie("playerKey")};
		ws.send(JSON.stringify(msg));
		console.log("message sent: " + JSON.stringify(msg));
	};
	
	ws.onerror = function(event) {
		console.log("an error has occured");
		console.log(event);
	};
	
	ws.onmessage = function(event) {
		console.log("message received");
		console.log("json::: " + event.data);
		var data = jQuery.parseJSON(event.data);
		if (data.success){
			switch(data.action){
				case "registerPlayerToSocket":
					console.log("player registration succeeded " + data.loggedPlayer.facebookId + " " + data.loggedPlayer.status);
					break;
				case "startGame":
					console.log("player registration succeeded for everyone, game started");
					players = data.players;
					players[0].mark = "circle";
					players[1].mark = "x";
					me = getPlayerById($.cookie("playerId"));
					createFacebookData(players[0]);
					createFacebookData(players[1]);
					writeFacebookData();
					setPlayerInTurn(players[0]);
					break;
				case "writeToChat":
					writeInChat(getPlayerById(data.senderId), data.text);
					break;
				case "yourTurn":
					setPlayerInTurn(me);
					setSelectable(data.selectableSquares);
					break;
				case "makeMove":
					var player = getPlayerById(data.playerId);
					// mark a square
					if (me.id != data.playerId){
						markSquare(player.mark, data.destinationSquarePosition);
					}
					// increment moves
					incrementMoves(player);
					// if the game is over
					if (data.gameOver){
						if (data.winnerId !== undefined){
							console.log("not a draw");
							if (data.winnerId == me.id) gameOver(WIN);
							else gameOver(LOSS);
						} else{
							console.log("draw");
							gameOver(DRAW);
						}
					} else{
						// set the player in turn
						setPlayerInTurn(getPlayerById(data.playerInTurnId));
					}
			}
		} else{
			console.log("'" + data.action + "' failed.");
		}
		
	};
		
	ws.onclose = function(event) {
		console.log("connection closed");
	};
}

function createFacebookData(player){
	var query = player.facebookId + "?fields=name,picture";
	var jsonUrl = "https://graph.facebook.com/" + query + "&access_token=" + accessToken;
	
	$.ajax({
		type: 'GET',
		url: jsonUrl,
		dataType: 'json',
		success: function(data){
			player.username = data.name;
			player.picture = data.picture.data.url;
		},
		data: {},
		async: false
	});
}

function writeFacebookData(){
	$("#facebook_username_0").html(players[0].username);
	$("#facebook_picture_0").attr("src", players[0].picture);
	$("#facebook_username_1").html(players[1].username);
	$("#facebook_picture_1").attr("src", players[1].picture);
}

function setPlayerInTurn(player){
	var index = players.indexOf(player);
	if (index == 0){
		$("#player_0_box").addClass("active");
		$("#player_0_inner_box").addClass("active");
		$("#player_1_box").removeClass("active");
		$("#player_1_inner_box").removeClass("active");
	} else{
		$("#player_0_box").removeClass("active");
		$("#player_0_inner_box").removeClass("active");
		$("#player_1_inner_box").addClass("active");
		$("#player_1_box").addClass("active");
	}
}

function getPlayerById(id){
	for(var i = 0; i < players.length; i++){
		if (players[i].id == id){
			return players[i];
		}
	}
}

function getSquareByPosition(pos){
	var rowCol = getRowAndColByPosition(pos);
	return board[rowCol[0]][rowCol[1]];
}

function getRowAndColByPosition(pos){
	var row = Math.floor(pos / 3);
	var col = pos % 3;
	return [row, col];
}

function gameOver(condition){
	$("#modal").show();
	$("#leave_room").show();
	if (condition == WIN) $("#endgame_message").addClass("win");
	else if (condition == LOSS) $("#endgame_message").addClass("lose");
	else $("#endgame_message").addClass("draw");
	$("#endgame_message").show();
	$("#modal").bind("click", leaveRoomAfterGameIsOver);
	$("#endgame_message").bind("click", leaveRoomAfterGameIsOver);
}

function leaveRoomAfterGameIsOver(){
	// send message to end room
	ws.close();
	window.location.replace("gamehub.html");
}

function incrementMoves(player){
	var index = players.indexOf(player);
	var moves = parseInt($("#player_" + index + "_jogadas").html());
	$("#player_" + index + "_jogadas").html(moves + 1);
}

/**************************************
/* Websockets: send message functions *
/**************************************/

function sendChatMessage(string){
	var message = {action: "writeToChat", text: string};
	ws.send(JSON.stringify(message));
}

function sendMoveMessage(row, col){
	var message = {
		action: "makeMove",
		destinationSquarePosition: row * 3 + col
	};
	ws.send(JSON.stringify(message));
	lastMessage = JSON.stringify(message);
	console.log("message sent: " + JSON.stringify(message));
}

/*****************************************
/* Board functions: board initialization *
/*****************************************/

function initializeBoard(){
	var divs = $("td[id^='square']");
	for (var i = 0; i < 3; i++){
		board[i] = new Array(3);
	}
	for (var i = 0; i < divs.length; i++){
		// register in board
		var values = $(divs[i]).attr("id").split(":"); 
		var row = values[1];
		var col = values[2];
		board[row][col] = divs[i];
	}
}

/****************************************
/* Board functions: board modifications *
/****************************************/

function markSquare(mark, position){
	$(getSquareByPosition(position)).addClass(mark);
}

function makeMove(row, col){
	sendMoveMessage(row, col);
	$(board[row][col]).addClass(me.mark);
	for (var i = 0; i < board.length; i++){
		for (var j = 0; j < board[0].length; j++){
			$(board[i][j]).removeClass("selectable");
			$(board[i][j]).unbind();
		}
	}
}

function setSelectable(positions){
	for (var i = 0; i < positions.length; i++){
		$(getSquareByPosition(positions[i])).addClass("selectable");
		$(getSquareByPosition(positions[i])).bind("click", {position: positions[i]}, function(event){
			var rowCol = getRowAndColByPosition(event.data.position);
			console.log(event.data.position + " " + rowCol[0] + " " + rowCol[1]);
			makeMove(rowCol[0], rowCol[1]);
		});
	}
}

/****************************************************************
/* Board functions: utility functions (used by other functions) *
/****************************************************************/



/******************
/* Chat functions *
/******************/

function writeInChat(player, message){
	if (lastPlayerInChat == player){
		$("#message\\:" + (numberOfChatMessages - 1)).append("<p>" + message + "<p>");
	} else{
		if ($("#chat_content").html() != ""){
			$("#chat_content").append("<div class=\"chat_separator\"></div>");
		}
		var messageId = "message:" + numberOfChatMessages++;
		var html = "<div id=\"" + messageId + "\" class=\"chat_message\">";
		html += "<img src=\"" + player.picture + "\" width=\"30\" height=\"30\" alt=\"" + player.username + " said: \" />";
		html += "<p>" + message + "<p>";
		html += "</div>";
		$("#chat_content").append(html);
		lastPlayerInChat = player;
	}
}

function moveChatWindow(xOffset, yOffset){
	$("#chat").css("bottom", (parseInt(chatOriginalBottom) + yOffset) + "px");
	$("#chat").css("right", (parseInt(chatOriginalRight) + xOffset) + "px");
}

function bindChatWindow(){
	$("#chat_move_icon").click(function(event){
		if(!draggingChatWindow){
			chatOriginalRight = $("#chat").css("right").split("px")[0];
			chatOriginalBottom = $("#chat").css("bottom").split("px")[0];
			dragChatX = event.pageX;
			dragChatY = event.pageY;
			draggingChatWindow = true;
			event.stopPropagation();
		}
	});
	$("body").mousemove(function(event){
		if(draggingChatWindow){
			moveChatWindow(dragChatX - event.pageX, dragChatY - event.pageY);
		}
	});
	$("body").click(function(event){
		draggingChatWindow = false;
	});
}